package com.xuchang.service.impl;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.xuchang.Feign.JwtToken;
import com.xuchang.Feign.OAuth2FeignClient;
import com.xuchang.domain.SysMenu;
import com.xuchang.model.LoginResult;
import com.xuchang.model.R;
import com.xuchang.service.SysLoginService;
import com.xuchang.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class SysLoginImpl implements SysLoginService {
    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;
    @Autowired
    private SysMenuService sysMenuService;

    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String basicToken ;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public LoginResult userLogin(String username, String password) {
        ResponseEntity<JwtToken> tokenResponseEntity = oAuth2FeignClient.getToken("password", username, password, "admin", basicToken);
        if(tokenResponseEntity.getStatusCode()!= HttpStatus.OK){
            throw new ApiException(ApiErrorCode.FAILED);
        }
        // 查询我们的菜单数据
        JwtToken jwtToken = tokenResponseEntity.getBody();
        String accessToken = jwtToken.getAccessToken();
        String jwtJsonStr = JwtHelper.decode(accessToken).getClaims();
        JSONObject jwtJson = JSON.parseObject(jwtJsonStr);
        Long userId = Long.valueOf(jwtJson.getString("user_name")) ;
        List<SysMenu> menus = sysMenuService.getMenuByUserId(userId);

        // 权限数据jwt 里面已经包含了
        JSONArray authorities = jwtJson.getJSONArray("authorities");
        List<SimpleGrantedAuthority> authoritiesCollect = authorities.stream().map(authoritie -> new SimpleGrantedAuthority(authoritie.toString())).collect(Collectors.toList());
        // 将该token 存储在redis 里面，配置我们的网关做jwt验证的操作
        redisTemplate.opsForValue().set(accessToken,"",jwtToken.getExpiresIn(), TimeUnit.SECONDS);
        // 我们返回给前端的Token 数据，少一个bearer：
        return new LoginResult(jwtToken.getTokenType()+" "+ accessToken,menus,authoritiesCollect);
    }
}
